#include "calculator_ui.h"
#include "esp_lvgl_port.h"
#include "esp_log.h"
#include "main_ui.h"
#include "md_images.h"
#include "func_pin_image.h"
#include "md_languages.h"
#include <ctype.h>
#include <stdlib.h>
#include <string.h>

// 声明字体
LV_FONT_DECLARE(myFont);
LV_FONT_DECLARE(lv_font_montserrat_14);

// 按钮布局 - 调整为更紧凑的布局
static const char *btnm_map[] = { "(", ")", "C", "<-", "\n",
                                  "7", "8", "9", "/", "\n",
                                  "4", "5", "6", "*", "\n",
                                  "1", "2", "3", "-", "\n",
                                  "0", ".", "=", "+", "" };

// 按钮控制映射
static const lv_btnmatrix_ctrl_t ctrl_map[] = {
    1, 1, LV_BTNMATRIX_CTRL_CHECKED, LV_BTNMATRIX_CTRL_CHECKED,
    1, 1, 1, LV_BTNMATRIX_CTRL_CHECKED,
    1, 1, 1, LV_BTNMATRIX_CTRL_CHECKED,
    1, 1, 1, LV_BTNMATRIX_CTRL_CHECKED,
    1, 1, LV_BTNMATRIX_CTRL_CHECKED, LV_BTNMATRIX_CTRL_CHECKED
};

// Token类型定义
typedef enum {
    TOKENIZER_ERROR = -1,
    TOKENIZER_ENDOFINPUT = 0,
    TOKENIZER_NUMBER,   // 数字
    TOKENIZER_PLUS,   // +
    TOKENIZER_MINUS,  // -
    TOKENIZER_ASTR,   // *
    TOKENIZER_SLASH,  // /
    TOKENIZER_LPAREN, // (
    TOKENIZER_RPAREN, // )
    TOKENIZER_DOT     // .
} token_t;

// 错误类型定义
typedef enum {
    NO_ERROR = 0,
    SYNTAX_ERROR
} error_t;

// 计算器数据结构
typedef struct {
    lv_obj_t *ta_hist;  // 历史记录文本框
    lv_obj_t *ta_input; // 输入文本框
    lv_obj_t *btnm;     // 按钮矩阵
    char calc_exp[256]; // 计算表达式
    int count;          // 表达式字符计数

    // 词法分析器状态
    const char *curr_char;
    const char *next_char;
    token_t current_token;
    error_t error_code;
} calculator_t;

static calculator_t *calc = NULL;

// 错误信息表
static const struct {
    error_t error_code;
    const char *message;
} error_table[] = {
    { NO_ERROR, "No error" },
    { SYNTAX_ERROR, "Syntax error!" }
};

// 词法分析器函数声明
static void tokenizer_init(const char *expr);
static token_t get_next_token(void);
static token_t single_char(char curr_char);
static int tokenizer_num(const char *curr_char);
static void tokenizer_next(void);
static bool tokenizer_finished(void);

// 语法分析器函数声明
static double parse_expression(void);
static double parse_term(void);
static int parse_factor(void);
static void accept(token_t token);
void exit_calculator_ui(lv_obj_t *root)
{
          switch_to_main_screen(); // 切换到主界面
            if (calc) {
                lv_mem_free(calc);
                calc = NULL;
            }
            /*因为功能界面多,而且不常用,所以删除*/
            lv_obj_del(root); //也可以把lv_scr_load_anim的auto_del设置为true
}

// 手势事件回调
static void event_handler(lv_event_t *e)
{
    lv_event_code_t code = lv_event_get_code(e);

    if (code == LV_EVENT_GESTURE) {
        lv_indev_t *indev = lv_indev_get_act();
        if (!indev)
            return;

        lv_dir_t dir = lv_indev_get_gesture_dir(indev);

        // 保留右划检测
        if (dir == LV_DIR_RIGHT || dir == LV_DIR_TOP) {
            exit_calculator_ui(e->target);
        }
    }
}
// 按钮事件回调函数
static void calc_btnm_changed_event_cb(lv_event_t *e)
{
    lv_obj_t *obj = lv_event_get_target(e);
    lv_event_code_t code = lv_event_get_code(e);

    if (code == LV_EVENT_VALUE_CHANGED) {
        uint32_t id = lv_btnmatrix_get_selected_btn(obj);
        const char *txt = lv_btnmatrix_get_btn_text(obj, id);

        // 执行操作
        if (strcmp(txt, "=") == 0) {
            char tmp_buff[32];
            double calc_results;

            // 词法分析器初始化
            tokenizer_init(calc->calc_exp);

            // 计算表达式值
            calc_results = parse_expression();

            if (calc->error_code != NO_ERROR) {
                // 查找错误代码并显示相应消息
                for (int i = 0; i < sizeof(error_table) / sizeof(error_table[0]); i++) {
                    if (error_table[i].error_code == calc->error_code) {
                        lv_textarea_add_text(calc->ta_hist, "\n");
                        lv_textarea_add_text(calc->ta_hist, error_table[i].message);
                        lv_textarea_add_text(calc->ta_hist, "\n");
                        break;
                    }
                }
                calc->error_code = NO_ERROR; // 重置错误代码
            } else {
                // 格式化结果显示
                snprintf(tmp_buff, sizeof(tmp_buff), "%s = %.2f\n", calc->calc_exp, calc_results);
                lv_textarea_add_text(calc->ta_hist, tmp_buff);
                lv_textarea_set_text(calc->ta_input, tmp_buff);
                // 清空表达式
                memset(calc->calc_exp, 0, sizeof(calc->calc_exp));
                calc->count = 0;
            }
        }
        // 清除
        else if (strcmp(txt, "C") == 0) {
            lv_textarea_set_text(calc->ta_input, "");
            memset(calc->calc_exp, 0, sizeof(calc->calc_exp));
            calc->count = 0;
        }
        // 删除字符
        else if (strcmp(txt, "<-") == 0) {
            lv_textarea_del_char(calc->ta_input);
            if (calc->count > 0) {
                calc->calc_exp[--calc->count] = '\0';
            }
        }
        // 添加字符
        else {
            lv_textarea_add_text(calc->ta_input, txt);
            if (calc->count < (int)sizeof(calc->calc_exp) - 1) {
                calc->calc_exp[calc->count++] = txt[0];
                calc->calc_exp[calc->count] = '\0';
            }
        }
    }
}


// 词法分析器初始化
static void tokenizer_init(const char *expr)
{
    calc->curr_char = expr;
    calc->next_char = expr;
    calc->current_token = get_next_token();
    calc->error_code = NO_ERROR;
}

// 获取下一个token
static token_t get_next_token(void)
{
    int i;

    // 表达式结束
    if (*calc->curr_char == '\0')
        return TOKENIZER_ENDOFINPUT;

    if (isdigit((unsigned char)*calc->curr_char)) {
        // 检查数字长度是否超过允许的最大长度
        for (i = 0; i <= 10; i++) {
            if (!isdigit((unsigned char)*(calc->curr_char + i))) {
                calc->next_char = calc->curr_char + i;
                return TOKENIZER_NUMBER;
            }
        }
    }
    // 分隔符（运算符和括号）
    else if (single_char(*calc->curr_char) != TOKENIZER_ERROR) {
        calc->next_char = calc->curr_char + 1;
        return single_char(*calc->curr_char);
    }

    return TOKENIZER_ERROR;
}

// 获取单字符token类型
static token_t single_char(char curr_char)
{
    switch (curr_char) {
        case '+':
            return TOKENIZER_PLUS;
        case '-':
            return TOKENIZER_MINUS;
        case '*':
            return TOKENIZER_ASTR;
        case '/':
            return TOKENIZER_SLASH;
        case '(':
            return TOKENIZER_LPAREN;
        case ')':
            return TOKENIZER_RPAREN;
        case '.':
            return TOKENIZER_DOT;
        default:
            break;
    }

    return TOKENIZER_ERROR;
}

// 将ASCII字符串转换为数值
static int tokenizer_num(const char *curr_char)
{
    return atoi(curr_char);
}

// 解析下一个token
static void tokenizer_next(void)
{
    if (tokenizer_finished())
        return;

    calc->curr_char = calc->next_char;
    calc->current_token = get_next_token();
}

// 判断token是否解析完成
static bool tokenizer_finished(void)
{
    return *calc->curr_char == '\0' || calc->current_token == TOKENIZER_ENDOFINPUT;
}

// 按照语法规则匹配当前token
static void accept(token_t token)
{
    if (token != calc->current_token) {
        calc->error_code = SYNTAX_ERROR;
    }
    tokenizer_next();
}

// 计算表达式值（处理加减运算）
static double parse_expression(void)
{
    double t1, t2 = 0;
    token_t op;

    // 获取第一个操作数（项）
    t1 = parse_term();
    // 获取运算符
    op = calc->current_token;

    // 处理连续的加减运算（同级优先级）
    while (op == TOKENIZER_PLUS || op == TOKENIZER_MINUS) {
        // 获取下一个token
        tokenizer_next();

        // 获取第二个操作数
        t2 = parse_term();
        switch (op) {
            case TOKENIZER_PLUS:
                t1 = t1 + t2;
                break;
            case TOKENIZER_MINUS:
                t1 = t1 - t2;
                break;
            default:
                break;
        }
        op = calc->current_token; // 获取下一个运算符
    }

    return t1;
}

// 计算项值（处理乘除运算）
static double parse_term(void)
{
    double f1, f2;
    token_t op;

    // 获取左操作数（因子）
    f1 = parse_factor();

    // 获取运算符
    op = calc->current_token;

    // 处理连续的乘除运算（同级优先级）
    while (op == TOKENIZER_ASTR || op == TOKENIZER_SLASH) {
        // 获取下一个token
        tokenizer_next();

        // 获取右操作数
        f2 = parse_factor();
        switch (op) {
            case TOKENIZER_ASTR:
                f1 = f1 * f2;
                break;
            case TOKENIZER_SLASH:
                if (f2 == 0) {
                    calc->error_code = SYNTAX_ERROR;
                    return 0;
                }
                f1 = f1 / f2;
                break;
            default:
                break;
        }
        // 计算后的值作为左操作数继续处理
        op = calc->current_token; // 获取下一个运算符
    }

    return f1;
}

// 获取因子值（处理数字和括号表达式）
static int parse_factor(void)
{
    int r = 0;

    // 根据当前token类型处理
    switch (calc->current_token) {
        // 数字（终结符）
        case TOKENIZER_NUMBER:
            // 将ASCII转换为数值
            r = tokenizer_num(calc->curr_char);
            // 按照语法规则匹配当前token
            accept(TOKENIZER_NUMBER);
            break;
        // 左括号
        case TOKENIZER_LPAREN:
            accept(TOKENIZER_LPAREN);
            // 将括号内的值作为新表达式递归计算
            r = parse_expression();
            // 括号内的表达式处理完后，下一个token必须是右括号
            accept(TOKENIZER_RPAREN);
            break;
        // 其他token类型视为语法错误
        default:
            calc->error_code = SYNTAX_ERROR;
    }

    return r;
}

lv_obj_t *create_calculator_ui(void)
{
    lvgl_port_lock(0);

    // 创建根容器
    lv_obj_t *root = lv_obj_create(NULL);
    if (!root)
        return NULL;

    lv_obj_set_size(root, 320, 240);
    lv_obj_set_style_bg_color(root, lv_color_black(), LV_PART_MAIN);
    lv_obj_add_event_cb(root, event_handler, LV_EVENT_GESTURE, NULL);
    lv_obj_set_style_pad_all(root, 0, 0);
    lv_obj_set_style_border_width(root, 0, 0);
    lv_obj_set_style_outline_width(root, 0, 0);
    lv_obj_set_scrollbar_mode(root, LV_SCROLLBAR_MODE_OFF);

    // 分配计算器数据结构内存
    calc = (calculator_t *)lv_mem_alloc(sizeof(calculator_t));
    if (!calc) {
        lv_obj_del(root);
        return NULL;
    }
    memset(calc, 0, sizeof(calculator_t));

    // 设置布局为列方向
    lv_obj_set_flex_flow(root, LV_FLEX_FLOW_COLUMN);
    lv_obj_set_flex_align(root, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_START);

    // 创建显示计算历史和结果的文本框
    calc->ta_hist = lv_textarea_create(root);
    lv_obj_set_style_bg_color(calc->ta_hist, lv_color_black(), 0);
    lv_obj_set_style_text_color(calc->ta_hist, lv_color_hex(0x00FF00), 0);
    lv_obj_set_style_radius(calc->ta_hist, 0, 0);
    lv_obj_set_style_text_font(calc->ta_hist, &lv_font_montserrat_14, 0); // 使用更小的字体
    lv_obj_set_style_border_width(calc->ta_hist, 0, 0);
    lv_obj_set_style_outline_width(calc->ta_hist, 0, 0);
    lv_obj_set_style_pad_all(calc->ta_hist, 2, 0); // 减少内边距

    lv_obj_set_size(calc->ta_hist, 320, 25); // 固定高度
    lv_textarea_set_cursor_click_pos(calc->ta_hist, false);
    lv_textarea_set_max_length(calc->ta_hist, 512);
    lv_textarea_set_align(calc->ta_hist, LV_TEXT_ALIGN_RIGHT);
    lv_textarea_set_text(calc->ta_hist, "");
    lv_textarea_set_placeholder_text(calc->ta_hist, "Calculator");
    lv_obj_set_scrollbar_mode(calc->ta_hist, LV_SCROLLBAR_MODE_ACTIVE);

    // 创建输入文本框
    calc->ta_input = lv_textarea_create(root);
    lv_obj_set_style_bg_color(calc->ta_input, lv_color_black(), 0);
    lv_obj_set_style_text_color(calc->ta_input, lv_color_white(), 0);
    lv_obj_set_style_radius(calc->ta_input, 0, 0);
    lv_obj_set_style_border_width(calc->ta_input, 0, 0);
    lv_obj_set_style_outline_width(calc->ta_input, 0, 0);
    lv_obj_set_style_text_font(calc->ta_input, &myFont, 0);

    lv_obj_set_size(calc->ta_input, 320, 25); // 固定高度
    lv_textarea_set_one_line(calc->ta_input, true);
    lv_textarea_set_cursor_click_pos(calc->ta_input, false);
    lv_textarea_set_max_length(calc->ta_input, 256);
    lv_textarea_set_align(calc->ta_input, LV_TEXT_ALIGN_RIGHT);
    lv_textarea_set_text(calc->ta_input, "");
    lv_obj_set_style_pad_all(calc->ta_input, 2, 0); // 减少内边距
    lv_obj_set_scrollbar_mode(calc->ta_input, LV_SCROLLBAR_MODE_OFF);

    // 创建计算器输入面板（按钮矩阵）
    calc->btnm = lv_btnmatrix_create(root);
    lv_obj_set_style_radius(calc->btnm, 0, 0);
    lv_obj_set_style_border_width(calc->btnm, 0, 0);
    lv_obj_set_style_outline_width(calc->btnm, 0, 0);
    lv_obj_set_style_bg_color(calc->btnm, lv_color_black(), 0);

    // 调整按钮矩阵大小
    lv_obj_set_size(calc->btnm, 320, 170); // 剩余空间
    lv_btnmatrix_set_map(calc->btnm, btnm_map);
    lv_btnmatrix_set_ctrl_map(calc->btnm, ctrl_map);
    lv_obj_add_event_cb(calc->btnm, calc_btnm_changed_event_cb, LV_EVENT_VALUE_CHANGED, NULL);

    // 设置按钮样式
    lv_obj_set_style_bg_color(calc->btnm, lv_color_hex(0x333333), LV_PART_ITEMS);
    lv_obj_set_style_bg_color(calc->btnm, lv_color_hex(0x555555), LV_PART_ITEMS | LV_STATE_PRESSED);
    lv_obj_set_style_text_color(calc->btnm, lv_color_white(), LV_PART_ITEMS);
    lv_obj_set_style_text_font(calc->btnm, &lv_font_montserrat_14, LV_PART_ITEMS); // 使用更小的字体
    lv_obj_set_style_pad_all(calc->btnm, 1, LV_PART_ITEMS);                        // 减少按钮内边距

    // 调整按钮矩阵的行和列间距
    lv_btnmatrix_set_btn_width(calc->btnm, 10, 64);
    lv_obj_set_style_pad_row(calc->btnm, 1, 0);    // 减少行间距
    lv_obj_set_style_pad_column(calc->btnm, 1, 0); // 减少列间距

    lvgl_port_unlock();
    return root;
}